package org.example.project_12.service.impl;

import org.example.project_12.dto.CreateDocumentDto;
import org.example.project_12.dto.DocumentDto;
import org.example.project_12.dto.UpdateDocumentDto;
import org.example.project_12.entity.Document;
import org.example.project_12.entity.Favorite;
import org.example.project_12.entity.Space;
import org.example.project_12.entity.SpaceDoc;
import org.example.project_12.mapper.*;
import org.example.project_12.service.DocumentService;
import org.example.project_12.service.SpaceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DocumentServiceImpl implements DocumentService {

    @Autowired
    private DocumentMapper documentMapper;

    @Autowired
    private FavoriteMapper favoriteMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private SpaceMapper spaceMapper;

    @Autowired
    private SpaceService spaceService;

    @Autowired
    private SpaceDocMapper spaceDocMapper;

    @Override
    @Transactional
    public DocumentDto createDocument(CreateDocumentDto createDocumentDto, Long authorId) {
        // 验证输入
        if (!StringUtils.hasText(createDocumentDto.getTitle()) || !StringUtils.hasText(createDocumentDto.getContent())) {
            throw new IllegalArgumentException("文档标题和内容不能为空");
        }

        // 创建文档
        String status = (createDocumentDto.getIsPublic() != null && createDocumentDto.getIsPublic()) ? "PENDING" : "PRIVATE";
        Document document = Document.builder()
                .title(createDocumentDto.getTitle().trim())
                .content(createDocumentDto.getContent())
                .authorId(authorId)
                .spaceId(createDocumentDto.getSpaceId())
                .isPublic(false) // 仅status为PUBLIC时才真正公开
                .lockedBy(null)
                .status(status)
                .build();

        document.onCreate();
        documentMapper.insert(document);

        // 插入space_doc
        if (document.getSpaceId() != null) {
            SpaceDoc spaceDoc = new SpaceDoc();
            spaceDoc.setSpaceId(document.getSpaceId());
            spaceDoc.setDocId(document.getId());
            spaceDoc.setLinkedAt(document.getCreatedAt());
            spaceDocMapper.insert(spaceDoc);
        }

        return convertToDocumentDto(document, authorId);
    }

    @Override
    public DocumentDto getDocumentById(Long documentId, Long userId) {
        Document document = documentMapper.selectById(documentId);
        if (document == null) {
            throw new IllegalArgumentException("文档不存在");
        }

        // 检查访问权限
        if (!hasPermissionToAccess(documentId, userId)) {
            throw new IllegalArgumentException("无权访问此文档");
        }

        return convertToDocumentDto(document, userId);
    }

    @Override
    public List<DocumentDto> getDocumentsByAuthor(Long authorId, Long currentUserId) {
        List<Document> documents = documentMapper.selectByAuthorId(authorId);

        return documents.stream()
                .map(doc -> convertToDocumentDto(doc, currentUserId))
                .collect(Collectors.toList());
    }

    @Override
    public List<DocumentDto> getDocumentsBySpace(Long spaceId, Long currentUserId) {
        List<Document> documents = documentMapper.selectBySpaceId(spaceId);

        return documents.stream()
                .filter(doc -> "PUBLIC".equals(doc.getStatus()))
                .map(doc -> convertToDocumentDto(doc, currentUserId))
                .collect(Collectors.toList());
    }

    @Override
    public List<DocumentDto> getPublicDocuments(Long currentUserId) {
        List<Document> documents = documentMapper.selectPublicDocuments();
        // 只返回status为PUBLIC的文档
        return documents.stream()
                .filter(doc -> "PUBLIC".equals(doc.getStatus()))
                .map(doc -> convertToDocumentDto(doc, currentUserId))
                .collect(Collectors.toList());
    }

    @Override
    public List<DocumentDto> searchDocumentsByTitle(String title, Long currentUserId) {
        List<Document> documents = documentMapper.selectByTitleLike(title);

        return documents.stream()
                .filter(doc -> hasPermissionToAccess(doc.getId(), currentUserId))
                .map(doc -> convertToDocumentDto(doc, currentUserId))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public DocumentDto updateDocument(Long documentId, UpdateDocumentDto updateDocumentDto, Long userId) {
        Document document = documentMapper.selectById(documentId);
        if (document == null) {
            throw new IllegalArgumentException("文档不存在");
        }

        // 检查编辑权限
        if (!hasPermissionToEdit(documentId, userId)) {
            throw new IllegalArgumentException("无权编辑此文档");
        }

        // 检查文档是否被锁定
        if (document.getLockedBy() != null && !document.getLockedBy().equals(userId)) {
            throw new IllegalArgumentException("文档正在被其他用户编辑");
        }

        // 锁定文档
        if (documentMapper.lockDocument(documentId, userId) == 0) {
            throw new IllegalArgumentException("文档已被锁定");
        }

        Long oldSpaceId = document.getSpaceId();

        try {
            // 更新文档
            if (StringUtils.hasText(updateDocumentDto.getTitle())) {
                document.setTitle(updateDocumentDto.getTitle().trim());
            }
            if (StringUtils.hasText(updateDocumentDto.getContent())) {
                document.setContent(updateDocumentDto.getContent());
            }
            if (updateDocumentDto.getIsPublic() != null) {
                document.setIsPublic(updateDocumentDto.getIsPublic());
            }

            document.onUpdate();
            documentMapper.update(document);

            documentMapper.update(document);
        // 处理space_doc关联
        if (updateDocumentDto.getSpaceId() != null && !updateDocumentDto.getSpaceId().equals(oldSpaceId)) {
            spaceDocMapper.deleteByDocId(documentId);
            SpaceDoc spaceDoc = new SpaceDoc();
            spaceDoc.setSpaceId(updateDocumentDto.getSpaceId());
            spaceDoc.setDocId(documentId);
            spaceDoc.setLinkedAt(document.getUpdatedAt());
            spaceDocMapper.insert(spaceDoc);
        }

            return convertToDocumentDto(document, userId);
        } finally {
            // 解锁文档
            documentMapper.unlockDocument(documentId);
        }


    }

    @Override
    @Transactional
    public boolean deleteDocument(Long documentId, Long userId) {
        Document document = documentMapper.selectById(documentId);
        if (document == null) {
            throw new IllegalArgumentException("文档不存在");
        }
        if (!document.getAuthorId().equals(userId)) {
            throw new IllegalArgumentException("只有文档作者可以删除文档");
        }
        // 删除space_doc关联
        spaceDocMapper.deleteByDocId(documentId);
        favoriteMapper.deleteByDocumentId(documentId);
        return documentMapper.deleteById(documentId) > 0;
    }

    @Override
    public boolean lockDocument(Long documentId, Long userId) {
        if (!hasPermissionToEdit(documentId, userId)) {
            throw new IllegalArgumentException("无权编辑此文档");
        }

        return documentMapper.lockDocument(documentId, userId) > 0;
    }

    @Override
    public boolean unlockDocument(Long documentId, Long userId) {
        Document document = documentMapper.selectById(documentId);
        if (document == null) {
            throw new IllegalArgumentException("文档不存在");
        }

        // 只有锁定者可以解锁
        if (!userId.equals(document.getLockedBy())) {
            throw new IllegalArgumentException("只有锁定者可以解锁文档");
        }

        return documentMapper.unlockDocument(documentId) > 0;
    }

    @Override
    public boolean favoriteDocument(Long documentId, Long userId) {
        if (!hasPermissionToAccess(documentId, userId)) {
            throw new IllegalArgumentException("无权访问此文档");
        }

        // 检查是否已收藏
        if (favoriteMapper.isFavorited(userId, documentId)) {
            throw new IllegalArgumentException("文档已收藏");
        }

        Favorite favorite = Favorite.builder()
                .userId(userId)
                .documentId(documentId)
                .build();

        favorite.onCreate();
        return favoriteMapper.insert(favorite) > 0;
    }

    @Override
    public boolean unfavoriteDocument(Long documentId, Long userId) {
        return favoriteMapper.deleteByUserIdAndDocumentId(userId, documentId) > 0;
    }

    @Override
    public List<DocumentDto> getFavoriteDocuments(Long userId) {
        List<Favorite> favorites = favoriteMapper.selectByUserId(userId);

        return favorites.stream()
                .map(favorite -> {
                    Document document = documentMapper.selectById(favorite.getDocumentId());
                    return document != null ? convertToDocumentDto(document, userId) : null;
                })
                .filter(dto -> dto != null)
                .collect(Collectors.toList());
    }

    @Override
    public boolean isDocumentFavorited(Long documentId, Long userId) {
        return favoriteMapper.isFavorited(userId, documentId);
    }

    @Override
    public String exportDocumentAsTxt(Long documentId, Long userId) {
        Document document = documentMapper.selectById(documentId);
        if (document == null) {
            throw new IllegalArgumentException("文档不存在");
        }

        if (!hasPermissionToAccess(documentId, userId)) {
            throw new IllegalArgumentException("无权访问此文档");
        }

        // 生成TXT格式内容
        StringBuilder content = new StringBuilder();
        content.append("标题: ").append(document.getTitle()).append("\n");
        content.append("作者: ").append(userMapper.selectById(document.getAuthorId()).getUsername()).append("\n");
        content.append("创建时间: ").append(document.getCreatedAt()).append("\n");
        content.append("更新时间: ").append(document.getUpdatedAt()).append("\n");
        content.append("\n");
        content.append("内容:\n");
        content.append(document.getContent());

        return content.toString();
    }

    @Override
    public boolean hasPermissionToAccess(Long documentId, Long userId) {
        Document document = documentMapper.selectById(documentId);
        if (document == null) {
            return false;
        }
        // 文档作者可以访问
        if (document.getAuthorId().equals(userId)) {
            return true;
        }
        // 只有status为PUBLIC的文档才可被他人访问
        if ("PUBLIC".equals(document.getStatus())) {
            return true;
        }
        // 空间成员可以访问
        if (document.getSpaceId() != null) {
            return spaceService.isUserMemberOfSpace(document.getSpaceId(), userId);
        }
        return false;
    }

    @Override
    public boolean hasPermissionToEdit(Long documentId, Long userId) {
        Document document = documentMapper.selectById(documentId);
        if (document == null) {
            return false;
        }

        // 文档作者可以编辑
        if (document.getAuthorId().equals(userId)) {
            return true;
        }

        // 空间成员可以编辑（需要检查空间成员权限）
        if (document.getSpaceId() != null) {
            // 这里需要调用空间服务检查成员权限，暂时返回false
            // TODO: 实现空间成员权限检查
            return false;
        }

        return false;
    }

    @Override
    public boolean updateDocumentStatus(Long documentId, String status) {
        return documentMapper.updateStatus(documentId, status) > 0;
    }
    @Override
    public List<DocumentDto> getDocumentsByStatus(String status) {
        List<Document> documents = documentMapper.selectByStatus(status);
        return documents.stream().map(doc -> convertToDocumentDto(doc, null)).collect(java.util.stream.Collectors.toList());
    }

    private DocumentDto convertToDocumentDto(Document document, Long currentUserId) {
        DocumentDto dto = new DocumentDto();
        dto.setId(document.getId());
        dto.setTitle(document.getTitle());
        dto.setContent(document.getContent());
        dto.setAuthorId(document.getAuthorId());
        dto.setAuthorName(userMapper.selectById(document.getAuthorId()).getUsername());
        dto.setSpaceId(document.getSpaceId());
        // 查找所有空间名
        Long spaceId = spaceDocMapper.selectSpaceIdByDocId(document.getId());
        Space space = spaceMapper.selectById(spaceId);
        if (space != null) {
            dto.setSpaceName(space.getName());
        } else {
            dto.setSpaceName("个人文档");
        }

        dto.setIsPublic(document.getIsPublic());
        dto.setLockedBy(document.getLockedBy());
        dto.setLockedByName(document.getLockedBy() != null ? userMapper.selectById(document.getLockedBy()).getUsername() : null);
        dto.setCreatedAt(document.getCreatedAt());
        dto.setUpdatedAt(document.getUpdatedAt());
        dto.setIsFavorited(favoriteMapper.isFavorited(currentUserId, document.getId()));
        dto.setStatus(document.getStatus());
        return dto;
    }

} 